/*
** Copyright (c) 2009  Kimmo 'Rainy' Pekkola
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program.  If not, see http://www.gnu.org/licenses.
*/

#include "precompiled.h"
#include "custombutton.h"

//-----------------------------------------------------------------------------
/**
** Constructor.
*/
CCustomButton::CCustomButton(QObject* pParent) : QObject(pParent), QGraphicsItem()
{
    m_State = State_Normal;
    m_bIgnoreRelease = false;

    bool bOk = connect(&m_HoldTimer, SIGNAL(timeout()), this, SLOT(onHoldTimeout()));
    Q_ASSERT(bOk);
}

//-----------------------------------------------------------------------------
/**
** Destructor
*/
CCustomButton::~CCustomButton()
{
}

//-----------------------------------------------------------------------------
/**
** Sets the graphics used in the button.
**
** \param pxBackground Thebackground image.
** \param pxIcon The icon which is placed on the button.
** \param iconOffset The icon offset from the center.
*/
void CCustomButton::setGraphics(const QPixmap& pxBackground, const QPixmap& pxIcon, QSizeF buttonSize, QPointF iconOffset)
{
    m_pxBackground = pxBackground;
    m_pxIcon = pxIcon;
    m_IconOffset = iconOffset;
    if (buttonSize.isEmpty())
    {
        m_ButtonSize = m_pxBackground.size();
    }
    else
    {
        m_ButtonSize = buttonSize;
    }
    update();
}

//-----------------------------------------------------------------------------
/**
** Sets the icon used in the button.
**
** \param strIcon The name of the icon.
*/
void CCustomButton::setIcon(const QPixmap& pxIcon)
{
    m_pxIcon = pxIcon;
    update();
}

//-----------------------------------------------------------------------------
/**
** Returns the bounding rect of the item. This is relative to the current position.
**
** \return The bounding rectangle.
*/
QRectF CCustomButton::boundingRect() const
{
    return QRectF(QPointF(0, 0), m_ButtonSize);
}

//-----------------------------------------------------------------------------
/**
** Paints the button with the given painter.
**
** \param pPainter The painter to be used.
** \param pOption The style options.
** \param pWidget The widget where the painting will be done.
*/
void CCustomButton::paint(QPainter* pPainter, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget)
{
    Q_UNUSED(pOption);
    Q_UNUSED(pWidget);

    if (!m_pxBackground.isNull())
    {
        pPainter->drawPixmap(0, 0, m_pxBackground.width(), m_pxBackground.height(), m_pxBackground);
    }

    QPointF pos((m_ButtonSize.width() - m_pxIcon.width() / 2) / 2, (m_ButtonSize.height() - m_pxIcon.height()) / 2);
    pPainter->drawPixmap(pos + m_IconOffset, m_pxIcon, QRectF(m_State * m_pxIcon.width() / 2, 0, m_pxIcon.width() / 2, m_pxIcon.height()));
}

//-----------------------------------------------------------------------------
/**
** Handler for the mouse press events. Changes the state of the button.
**
** \param pEvent The mouse event.
*/
void CCustomButton::mousePressEvent(QGraphicsSceneMouseEvent* pEvent)
{
    Q_UNUSED(pEvent);

    m_State = State_Pushed;
    m_HoldTimer.start(1000);
    update();
}

//-----------------------------------------------------------------------------
/**
** Handler for the mouse release events. Changes the state of the button.
**
** \param pEvent The mouse event.
*/
void CCustomButton::mouseReleaseEvent(QGraphicsSceneMouseEvent* pEvent)
{
    if (boundingRect().contains(pEvent->pos()) && !m_bIgnoreRelease)
    {
        emit clicked();
    }

    m_HoldTimer.stop();
    m_State = State_Normal;
    m_bIgnoreRelease = false;
    update();
}

/**
** Handler for hold timer. Emits clickAndHold and suppresses the next release event.
*/
void CCustomButton::onHoldTimeout()
{
    m_HoldTimer.stop();
    m_bIgnoreRelease = true;
    emit clickAndHold();
}

// EOF
